package org.jeecg.modules.product.sign.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.product.sign.entity.TbSignRecord;
import org.jeecg.modules.product.sign.entity.TbSignRule;
import org.jeecg.modules.product.sign.mapper.TbSignRecordMapper;
import org.jeecg.modules.product.sign.mapper.TbSignRuleMapper;
import org.jeecg.modules.product.sign.service.ITbSignRecordService;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * @Description: 打开记录
 * @Author: jeecg-boot
 * @Date:   2025-02-24
 * @Version: V1.0
 */
@Slf4j
@Service
public class TbSignRecordServiceImpl extends ServiceImpl<TbSignRecordMapper, TbSignRecord> implements ITbSignRecordService, Job {

    @Autowired
    private TbSignRecordMapper tbSignRecordMapper;
    @Autowired
    private TbSignRuleMapper tbSignRuleMapper;

    @Override
    public Boolean signIn(TbSignRecord tbSignRecord) {
        TbSignRule signRule = tbSignRuleMapper.selectOne(new QueryWrapper<>());
        /*1.先判定是否有凯芹规则，如果有考勤规则需要走考勤规则，如果没有就正常打卡上班，状态为正常*/
        if (signRule != null) {
            boolean isWithinRange =  findSignRule(signRule, tbSignRecord.getSignTime());
            /*1.根据是否存在走不同的逻辑,存在的话就是加班卡，如果不在范围内就需要打卡，再判定是否迟到*/
            if (isWithinRange) {
                tbSignRecord.setStatus("2");
            }else {
                /*1，上班卡，2，下班卡3，外出卡4，请假5，出差*/
                /*1,缺卡2,正常3,迟到4,旷工5,早退*/
                if (tbSignRecord.getType().equals("1")) {
                    tbSignRecord = goToWorkdetermineSignStatus(tbSignRecord,signRule);
                }else if(tbSignRecord.getType().equals("2")) {
                    tbSignRecord = afterWorkdetermineSignStatus(tbSignRecord,signRule);
                } else if (tbSignRecord.getType().equals("3")) {
                    tbSignRecord = goToWorkdetermineSignStatus(tbSignRecord,signRule);
                }else if (tbSignRecord.getType().equals("4")) {
                    tbSignRecord = goToWorkdetermineSignStatus(tbSignRecord,signRule);
                }else if (tbSignRecord.getType().equals("5")) {
                    tbSignRecord = goToWorkdetermineSignStatus(tbSignRecord,signRule);
                }
            }
            return tbSignRecordMapper.insert(tbSignRecord) > 0;
        }else {
            tbSignRecord.setStatus("2");
            return tbSignRecordMapper.insert(tbSignRecord) > 0;
        }
    }

    /**
     * 上班打卡状态判定
     * @param tbSignRecord
     * @param signRule
     * @return
     */
    private TbSignRecord goToWorkdetermineSignStatus(TbSignRecord tbSignRecord,TbSignRule signRule) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("mm:ss");
        /*上班时间*/
        String workingTime = signRule.getWorkingTime();
        /*上班迟到时间*/
        String workingLateTime = signRule.getWorkingLateTime();
        /*上班旷工时间*/
        String workingAbsenteeismTime = signRule.getWorkingAbsenteeismTime();
        /*签到时间*/
        String shortSignTime = DateUtils.formatShortTime(tbSignRecord.getSignTime());

        LocalTime parsedWorkingTime = LocalTime.parse(workingTime, formatter);
        LocalTime parsedWorkingLateTime = LocalTime.parse(workingLateTime, formatter);
        LocalTime parsedWorkingAbsenteeismTime = LocalTime.parse(workingAbsenteeismTime, formatter);
        LocalTime parsedShortSignTime = LocalTime.parse(shortSignTime, formatter);

        /*如果签到时间在迟到时间之前，就算是正常打卡，
        * 如果签到时间在迟到时间和旷工时间之间，就是迟到打卡
        * 如果签到时间在旷工时间之后，就是旷工打卡
        * 1,缺卡2,正常3,迟到4,旷工5,早退*/
        if (parsedShortSignTime.compareTo(parsedWorkingLateTime)<0) {
            tbSignRecord.setStatus("2");
        }else if(parsedShortSignTime.compareTo(parsedWorkingAbsenteeismTime)>=0) {
            tbSignRecord.setStatus("4");
        }else {
            tbSignRecord.setStatus("3");
        }
        return tbSignRecord;
    }

    /**
     * 下班打卡状态判定
     * @param tbSignRecord
     * @param signRule
     * @return
     */
    private TbSignRecord afterWorkdetermineSignStatus(TbSignRecord tbSignRecord,TbSignRule signRule) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("mm:ss");
        /*下班时间*/
        String offdutyTime = signRule.getOffdutyTime();
        /*下班早退时间*/
        String rarlyDepartureTime = signRule.getEarlyDepartureTime();
        /*签到时间*/
        String shortSignTime = DateUtils.formatShortTime(tbSignRecord.getSignTime());

        LocalTime parsedShortSignTime = LocalTime.parse(shortSignTime, formatter);
        LocalTime parsedOffdutyTime = LocalTime.parse(offdutyTime, formatter);
        LocalTime parsedEarlyDepartureTime = LocalTime.parse(rarlyDepartureTime, formatter);

        /*如果签到时间在下班时间之后，就算是正常打卡下班，
         * 如果签到时间在下班时间之之前和早退时间，就是迟到打卡
         * 如果签到时间在旷工时间之后，就是旷工打卡
         * 1,缺卡2,正常3,迟到4,旷工5,早退*/
        if (parsedOffdutyTime.compareTo(parsedShortSignTime)<=0) {
            tbSignRecord.setStatus("2");
        }else {
            /*如果签到时间小于早退时间就是早退
            * 如果签到时间大于早退时间就是正常*/
            if (parsedShortSignTime.compareTo(parsedEarlyDepartureTime)>=0) {
                tbSignRecord.setStatus("2");
            }else {
                tbSignRecord.setStatus("5");
            }
        }
        return tbSignRecord;
    }


    private boolean findSignRule(TbSignRule signRules, Date signDate) {
        /*如果在这几个时间区间范围呢，就返回true*/
        boolean isWithinRange = false;
        //元旦节
        if (signRules.getNewYearDayStartDate() != null && signRules.getNewYearDayEndDate() != null) {
            isWithinRange = !signDate.before(signRules.getNewYearDayStartDate()) && !signDate.after(signRules.getNewYearDayEndDate());
        }
        //春节节
        else if (signRules.getSpringFestivalStartDate() != null && signRules.getSpringFestivalEndDate() != null) {
            isWithinRange = !signDate.before(signRules.getSpringFestivalStartDate()) && !signDate.after(signRules.getSpringFestivalEndDate());
        }
        //清明节
        else if (signRules.getQingmingStartDate() != null && signRules.getQingmingEndDate() != null) {
            isWithinRange = !signDate.before(signRules.getQingmingStartDate()) && !signDate.after(signRules.getQingmingEndDate());
        }
        //五一劳动节
        else if (signRules.getMayDayStartDate() != null && signRules.getMayDayEndDate() != null) {
            isWithinRange = !signDate.before(signRules.getMayDayStartDate()) && !signDate.after(signRules.getMayDayEndDate());
        }
        //端午节
        else if (signRules.getDragonBoatFestivalStartDate() != null && signRules.getDragonBoatFestivalEndDate() != null) {
            isWithinRange = !signDate.before(signRules.getDragonBoatFestivalStartDate()) && !signDate.after(signRules.getDragonBoatFestivalEndDate());
        }
        //中秋节
        else if (signRules.getMidAutumnFestivalStartDate() != null && signRules.getMidAutumnFestivalEndDate() != null) {
            isWithinRange = !signDate.before(signRules.getMidAutumnFestivalStartDate()) && !signDate.after(signRules.getMidAutumnFestivalEndDate());
        }
        //国庆节
        else if (signRules.getNationalDayStartDate() != null && signRules.getNationalDayEndDate() != null) {
            isWithinRange = !signDate.before(signRules.getNationalDayStartDate()) && !signDate.after(signRules.getNationalDayEndDate());
        }
        //其他节
        else if (signRules.getOtherStartDate() != null && signRules.getOtherEndDate() != null) {
            isWithinRange = !signDate.before(signRules.getOtherStartDate()) && !signDate.after(signRules.getOtherEndDate());
        }
        return isWithinRange;
    }

    public static void main(String[] args) {
    }

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        String parameter = String.valueOf(jobExecutionContext.getMergedJobDataMap().get("parameter"));//获取前端配置过来的积分配置编号
        log.info("========parameter=================",parameter);

        JobDetail jobDetail = jobExecutionContext.getJobDetail();
        log.info("=========jobDetail==============",jobDetail);

        Object obj = jobExecutionContext.get("obj");
        log.info("=========obj==============",obj);
    }
}
